home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
c_lib.arc
/
PCEXEC.C
< prev
next >
Wrap
Text File
|
1990-08-09
|
5KB
|
153 lines
/**
*
* Name pcexec -- Load and execute a program
*
* Synopsis ercode = pcexec(pfile,pcmd);
* int ercode Returned DOS 2.0 function error code
* char *pfile Name of file to load and execute
* char *pcmd Commmand line to pass to the program
*
* Description This function loads and executes the program whose file
* name is specified with pfile. The program is loaded and
* executed as if invoked from DOS with the command line
* specified in pcmd. The spawned program returns control
* when either execution ends or Ctrl/Break is pressed.
* A zero error code indicates successful execution; a
* positive error code reflects an error from the PCSHRINK
* function, and negative value from the DOS load function
* EXEC (4b).
*
* Returns ercode DOS 2.0 function error code
*
* Version 1.1 (C)Copyright Blaise Computing Inc. 1983, 1984
*
**/
#include <compiler.h>
struct segads /* Offset, segment address type */
{
unsigned r;
unsigned s;
};
#define ADS struct segads /* Abbreviation */
struct dreg
{
unsigned ax,bx,cx,dx,si,di,ds,es;
};
#define DOSREG struct dreg
#if LAT200
extern ADS _psp; /* Program segment prefix */
#endif
#if CI201A
extern ADS _pspseg;
#endif
#if LAT104 | CI133D
extern unsigned _pgmseg;
#endif
int pcexec(pfile,pcmd)
char *pfile,*pcmd;
{
struct parm_block
{
unsigned envseg; /* Segment of environment */
ADS cmd_ads; /* ADS of command line */
ADS fb1_ads; /* ADS of first and second file */
ADS fb2_ads; /* control blocks (FCB) */
} block_val;
DOSREG dos_reg;
ADS env_ads,loc_ads;
int ercode,cmd_len;
unsigned size,cs,ss,ds,es;
char *pcmd_line,*calloc();
#if CI201A & LDATA
unsigned long ptrtoabs();
#endif
ercode = pcshrink(&size); /* Release available memory */
if (ercode != 0)
return(ercode);
/* First set up the parameter block. Its address is placed in */
/* BX register when DOS is called. Notice that the double word */
/* pointers have the offset first then the segment. This is just */
/* like the ADS type. */
#if LAT104 | CI133D
env_ads.s = _pgmseg; /* The segment address of the */
#endif /* environment is at offset 2C */
#if LAT200 /* in the program segment prefix*/
env_ads.s = _psp.s;
#endif
#if CI201A
env_ads.s = _pspseg.s;
#endif
env_ads.r = 0x2c;
#if LDATA
#if CI201A
loc_ads.s = (unsigned)((ptrtoabs(&block_val.envseg) & 0xffff0L) >> 4L);
loc_ads.r = (unsigned)(ptrtoabs(&block_val.envseg) & 0xfL);
#else
loc_ads.s = (unsigned)(((long)(&block_val.envseg) & 0xffff0L) >> 4L);
loc_ads.r = (unsigned)((long)(&block_val.envseg) & 0xfL);
#endif
#else
utsreg(&cs,&ss,&ds,&es); /* Return segment reg values */
loc_ads.s = ds;
loc_ads.r = &block_val.envseg;
#endif
utslmove(&env_ads,&loc_ads,2); /* Copy parent's environment */
/* The command line must have a leading length byte followed by */
/* actual characters making up the string. */
cmd_len = strlen(pcmd);
pcmd_line = calloc(cmd_len + 3,1);
*pcmd_line = (char)cmd_len;
strcat(pcmd_line,pcmd); /* pcmd_line is in right format*/
#if LDATA
#if CI201A
block_val.cmd_ads.s = (unsigned)((ptrtoabs(pcmd_line) & 0xffff0L) >> 4L);
block_val.cmd_ads.r = (unsigned)(ptrtoabs(pcmd_line) & 0xfL);
#else
block_val.cmd_ads.s = (unsigned)(((long)(pcmd_line) & 0xffff0L) >> 4L);
block_val.cmd_ads.r = (unsigned)((long)(pcmd_line) & 0xfL);
#endif
#else
block_val.cmd_ads.s = ds;
block_val.cmd_ads.r = (unsigned)pcmd_line;
#endif
block_val.fb1_ads.r = 0x5c; /* FCBs are at 5c and 6c within */
block_val.fb1_ads.s = env_ads.s; /* the Program Segment Prefix */
block_val.fb2_ads.r = 0x6c;
block_val.fb2_ads.s = env_ads.s;
utinit(&dos_reg);
dos_reg.ax = 0x4b00; /* DOS function call 4b */
#if LDATA
#if CI201A
dos_reg.es = (unsigned)((ptrtoabs(&block_val) & 0xffff0L) >> 4L);
dos_reg.bx = (unsigned)(ptrtoabs(&block_val) & 0xfL);
dos_reg.ds = (unsigned)((ptrtoabs(pfile) & 0xffff0L) >> 4L);
dos_reg.dx = (unsigned)(ptrtoabs(pfile) & 0xfL);
#else
dos_reg.es = (unsigned)(((long)(&block_val) & 0xffff0L) >> 4L);
dos_reg.bx = (unsigned)((long)(&block_val) & 0xfL);
dos_reg.ds = (unsigned)(((long)(pfile) & 0xffff0L) >> 4L);
dos_reg.dx = (unsigned)((long)(pfile) & 0xfL);
#endif
#else
dos_reg.bx = (unsigned)&block_val;
dos_reg.dx = (unsigned)pfile;
#endif
ercode = -dos(&dos_reg); /* Return negative error code */
free(pcmd_line);
return(ercode);
}